<template>
	<div v-if="loading && currentPage === 1" class="h-full flex flex-row justify-center items-center">
		<base-loading class="mt-4 text-center" block />
	</div>
	<div
		ref="listRef"
		class="h-full overflow-y-auto overflow-x-hidden"
		:class="listClass"
		@scroll="handleScroll"
		v-else-if="items.length">
		<slot name="header"></slot>
		<template v-for="(item, index) in items" :key="index">
			<slot name="item" :item="item" :index="index" />
		</template>
		<p v-show="loading" class="text-center text-primary py-10">Loading more...</p>
		<p v-show="finish" class="text-center text-primary py-10">No more...</p>
	</div>
	<div class="h-full flex flex-row justify-center items-center pt-10 pb-20" v-else>
		<BaseEmpty />
	</div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { listExposeType } from '@/components/base/list/type.ts'
import BaseEmpty from '@/components/base/empty/index.vue'
import BaseLoading from '@/components/base/loading/index.vue'

const props = defineProps({
	listClass: {
		type: String
	},
	manual: {
		type: Boolean,
		default: false
	}
})

const items = ref<any>([])
const loading = ref(false)
const currentPage = ref(1)
const totalPage = ref(1)
const listRef = ref(null)
const finish = ref(false)
const emits = defineEmits(['request-more'])

const fetchData = async () => {
	loading.value = true
	emits('request-more', currentPage.value, (list: Array<[]>, totalItems: number) => {
		if (currentPage.value === 1) {
			items.value = [...list]
		} else {
			items.value = [...items.value, ...list]
		}
		totalPage.value = totalItems
		finish.value = false

		if (items.value.length >= totalItems) {
			finish.value = true
		}
		loading.value = false
	})
}

const handleScroll = (event: any) => {
	if (finish.value) {
		return false
	}

	const scrollableList = event.target

	const distanceToBottom =
		scrollableList.scrollHeight - (scrollableList.scrollTop + scrollableList.clientHeight)
	if (distanceToBottom <= 30) {
		if (!loading.value) {
			currentPage.value++
			fetchData()
		}
	}
}

const onRefresh = () => {
	finish.value = false
	currentPage.value = 1
	fetchData()
}

onMounted(() => {
	!props.manual && fetchData()
})

defineExpose<listExposeType>({
	onRefresh
})
</script>
<style lang="scss"></style>
